<script setup lang="ts">
import { h, ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { NModal, NCard, NForm, NGrid, NTag, NSpace, NFormItem, NFormItemGi, NTreeSelect, NInput, NRadioGroup, NRadio, NSelect, NDatePicker, NButton, NDataTable, NPagination, NPopconfirm, useNotification } from 'naive-ui'
import type { FormInst, FormRules, FormItemRule } from 'naive-ui'
import http from '@/tools/http'
import { useDictStore } from '@/stores/dictStore'
import { useUserStore } from '@/stores/userStore'
import { useOrgStore } from '@/stores/orgStore'

import userRoleModel from './user-role-model.vue'

const dictStore = useDictStore()
const userStore = useUserStore()
const orgStore = useOrgStore()
const router = useRouter()

type RowData = {
    userId?: string
    orgCode?: string
    accountStatus?: string
    userName?: string
    idType?: string
    idCode?: string
    idBeginDate?: string
    idExpDate?: undefined
    birthday?: string
    sex?: string
    nationality?: string
    telephone?: string
    email?: string
    address?: string
    remark?: string
}

const userInfoTableColumns: any = [
    {
        title: "用户编号(账号)",
        key: "userId",
        width: 116
    }, {
        title: "姓名",
        key: "userName",
        width: 100,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "所属机构",
        key: "orgCode",
        width: 170,
        ellipsis: {
            tooltip: true
        },
        render(rowData: RowData, rowIndex: number) {
            return orgStore.getOrgName(rowData.orgCode)
        }
    }, {
        title: "状态",
        key: "accountStatus",
        width: 70,
        render(rowData: RowData, rowIndex: number) {
            let statusType: "default" | "error" | "primary" | "info" | "success" | "warning" = "default"
            if (rowData.accountStatus === "0") {
                statusType = "success"
            } else if (rowData.accountStatus === "1") {
                statusType = "warning"
            } else if (rowData.accountStatus === "2") {
                statusType = "error"
            } else {
                statusType = "default"
            }
            return h(
                NTag,
                {
                    type: statusType
                },
                () => dictStore.dictItem("ACCOUNT_STATUS", rowData.accountStatus)
            )
        }
    }, {
        title: "出生日期",
        key: "birthday",
        width: 100
    }, {
        title: "性别",
        key: "sex",
        width: 52,
        render(rowData: RowData, rowIndex: number) {
            return dictStore.dictItem("SEX", rowData.sex)
        }
    }, {
        title: "民族",
        key: "nationality",
        width: 52,
        render(rowData: RowData, rowIndex: number) {
            return dictStore.dictItem("NATIONALITY", rowData.nationality)
        }
    }, {
        title: "手机号",
        key: "telephone",
        width: 114,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "邮箱",
        key: "email",
        width: 154,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "联系地址",
        key: "address",
        width: 100,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "证件类型",
        key: "idType",
        width: 80,
        render(rowData: RowData, rowIndex: number) {
            return dictStore.dictItem("ID_TYPE", rowData.idType)
        }
    }, {
        title: "证件号码",
        key: "idCode",
        width: 172,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "证件开始日期",
        key: "idBeginDate",
        width: 108
    }, {
        title: "证件结束日期",
        key: "idExpDate",
        width: 108
    }, {
        title: "创建日期",
        key: "createDate",
        width: 100
    }, {
        title: "注销日期",
        key: "cancelDate",
        width: 100
    }, {
        title: "备注信息",
        key: "remark",
        width: 100,
        ellipsis: {
            tooltip: true
        }
    }, {
        title: "操作",
        key: "actions",
        width: 400,
        fixed: 'right',
        render(rowData: RowData, rowIndex: number) {
            return h(NSpace, null,
                () => [
                    userStore.hasAuth("user:cancel") && rowData.accountStatus !== '9' ? h(
                        NPopconfirm,
                        {
                            onPositiveClick: (e: MouseEvent) => cancelAccount()
                        },
                        {
                            trigger: () => {
                                return h(
                                    NButton,
                                    {
                                        size: "small",
                                        onclick: () => openCancelUserInfo(rowData)
                                    },
                                    { default: () => "注销" }
                                )
                            },
                            default: () => { return "确认注销该用户？" }
                        }
                    ) : null,
                    userStore.hasAuth("user:freeze") && rowData.accountStatus !== '9' ? h(
                        NPopconfirm,
                        {
                            onPositiveClick: (e: MouseEvent) => {
                                if (rowData.accountStatus === '0') {
                                    freezeAccount()
                                }
                                if (rowData.accountStatus === '1') {
                                    unFreezeAccount()
                                }
                            }
                        },
                        {
                            trigger: () => {
                                return h(
                                    NButton,
                                    {
                                        size: "small",
                                        onclick: () => openFreezeUserInfo(rowData)
                                    },
                                    {
                                        default: () => {
                                            if (rowData.accountStatus === '0') {
                                                return "冻结"
                                            }
                                            if (rowData.accountStatus === '1') {
                                                return "解冻"
                                            }
                                        }
                                    }
                                )
                            },
                            default: () => {
                                if (rowData.accountStatus === '0') {
                                    return "确认冻结该用户？"
                                }
                                if (rowData.accountStatus === '1') {
                                    return "确认解冻该用户？"
                                }
                            }
                        }
                    ) : null,
                    userStore.hasAuth("auth") && rowData.accountStatus !== '9' ? h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => openUserAuth(rowData)
                        },
                        { default: () => "权限" }
                    ) : null,
                    userStore.hasAuth("user:role") && rowData.accountStatus !== '9' ? h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => openUserRole(rowData)
                        },
                        { default: () => "角色" }
                    ) : null,
                    userStore.hasAuth("user:reset-pwd") && rowData.accountStatus !== '9' ? h(
                        NPopconfirm,
                        {
                            onPositiveClick: (e: MouseEvent) => resetAccountPwd()
                        },
                        {
                            trigger: () => {
                                return h(
                                    NButton,
                                    {
                                        size: "small",
                                        onclick: () => openResetUserInfo(rowData)
                                    },
                                    { default: () => "重置密码" }
                                )
                            },
                            default: () => { return "确认重置该用户密码？" }
                        }
                    ) : null,
                    userStore.hasAuth("user:edit") && rowData.accountStatus !== '9' ? h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => openEditUserInfo(rowData)
                        },
                        { default: () => "编辑" }
                    ) : null
                ]
            )
        }
    }
]

const userInfoData = reactive<any>({
    list: [],
    pageNum: 1,
    pageSize: 10,
    pages: 1,
    total: 0
})

const userInfoSearchFormValue = reactive({
    pageNum: 1,
    pageSize: 10,
    userId: "",
    userName: ""
})

onMounted(() => {
    pageUserInfo()
})

const visiable = ref<boolean>(false)
const title = ref<string>("")
const formRef = ref<FormInst | null>(null)
const formData = reactive<RowData>({
    userId: "",
    orgCode: "",
    userName: "",
    idType: "00",
    idCode: "",
    idBeginDate: undefined,
    idExpDate: undefined,
    birthday: undefined,
    sex: "0",
    nationality: "00",
    telephone: "",
    email: "",
    address: "",
    remark: ""
})

const formRules: FormRules = ({
    userId: {
        required: true,
        message: '请生成用户编号(账号)',
        trigger: ['input']
    },
    orgCode: {
        required: true,
        message: '请选择所属机构',
        trigger: ['input']
    },
    userName: {
        required: true,
        message: '请输入姓名',
        trigger: ['input']
    },
    idType: {
        required: true,
        message: '请选择证件类型',
        trigger: ['input']
    },
    idCode: {
        required: true,
        trigger: ['input'],
        validator: (rule: FormItemRule, value: string): boolean | Error => {
            if (formData.idType === '00') {
                const regex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
                if (!value || value.length === 0) {
                    return new Error("请输入证件号码")
                }
                if (!regex.test(value)) {
                    return new Error("证件号码格式错误，请重新输入")
                }
            }
            return true
        }
    },
    birthday: {
        required: true,
        message: '请选择出生日期',
        trigger: ['input']
    },
    sex: {
        required: true,
        message: '请选择性别',
        trigger: ['input']
    },
    nationality: {
        required: true,
        message: '请选择民族',
        trigger: ['input']
    }
})

function pageNumChange(pageNum: number) {
    userInfoSearchFormValue.pageNum = pageNum
    pageUserInfo()
}

function pageSizeChange(pageSize: number) {
    userInfoSearchFormValue.pageSize = pageSize
    pageUserInfo()
}

function openAddUserInfo() {
    visiable.value = true
    title.value = "添加用户"
    formData.userId = ""
    formData.orgCode = ""
    formData.userName = ""
    formData.idType = "00"
    formData.idCode = ""
    formData.idBeginDate = undefined
    formData.idExpDate = undefined
    formData.birthday = undefined
    formData.sex = "0"
    formData.nationality = "00"
    formData.telephone = ""
    formData.email = ""
    formData.address = ""
    formData.remark = ""
}

function openEditUserInfo(row: RowData) {
    visiable.value = true
    title.value = "编辑用户"
    formData.userId = row.userId
    formData.orgCode = row.orgCode
    formData.userName = row.userName
    formData.idType = row.idType
    formData.idCode = row.idCode
    formData.idBeginDate = row.idBeginDate
    formData.idExpDate = row.idExpDate
    formData.birthday = row.birthday
    formData.sex = row.sex
    formData.nationality = row.nationality
    formData.telephone = row.telephone
    formData.email = row.email
    formData.address = row.address
    formData.remark = row.remark
}

function openFreezeUserInfo(row: RowData) {
    formData.userId = row.userId
    formData.orgCode = row.orgCode
    formData.userName = row.userName
    formData.idType = row.idType
    formData.idCode = row.idCode
    formData.idBeginDate = row.idBeginDate
    formData.idExpDate = row.idExpDate
    formData.birthday = row.birthday
    formData.sex = row.sex
    formData.nationality = row.nationality
    formData.telephone = row.telephone
    formData.email = row.email
    formData.address = row.address
    formData.remark = row.remark
}

function openCancelUserInfo(row: RowData) {
    formData.userId = row.userId
    formData.orgCode = row.orgCode
    formData.userName = row.userName
    formData.idType = row.idType
    formData.idCode = row.idCode
    formData.idBeginDate = row.idBeginDate
    formData.idExpDate = row.idExpDate
    formData.birthday = row.birthday
    formData.sex = row.sex
    formData.nationality = row.nationality
    formData.telephone = row.telephone
    formData.email = row.email
    formData.address = row.address
    formData.remark = row.remark
}

function openResetUserInfo(row: RowData) {
    formData.userId = row.userId
    formData.orgCode = row.orgCode
    formData.userName = row.userName
    formData.idType = row.idType
    formData.idCode = row.idCode
    formData.idBeginDate = row.idBeginDate
    formData.idExpDate = row.idExpDate
    formData.birthday = row.birthday
    formData.sex = row.sex
    formData.nationality = row.nationality
    formData.telephone = row.telephone
    formData.email = row.email
    formData.address = row.address
    formData.remark = row.remark
}

function submit() {
    formRef.value?.validate((errors) => {
        if (!errors) {
            if (title.value === "添加用户") {
                addUserInfo()
            } else {
                updateUserInfo()
            }
            visiable.value = false
        }
    })
}

function pageUserInfo() {
    http.post("/user/page", userInfoSearchFormValue).then(({ data }) => {
        if (data.code === "0") {
            userInfoData.pageNum = data.data.pageNum
            userInfoData.pageSize = data.data.pageSize
            userInfoData.pages = data.data.pages
            userInfoData.total = data.data.total
            userInfoData.list.length = 0
            for (let i = 0; i < data.data.list.length; i++) {
                userInfoData.list.push(data.data.list[i])
            }
        }
    })
}

const notification = useNotification()

function generateAccount() {
    http.post("/user/account/generate").then(({ data }) => {
        if (data.code === "0") {
            formData.userId = data.data
            notification['success']({
                content: '用户编号(账号)生成成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
        }
    })
}

function addUserInfo() {
    http.post("/user/add", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '添加成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageUserInfo()
        }
    })
}

function updateUserInfo() {
    http.post("/user/update", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '修改成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageUserInfo()
        }
    })
}

function freezeAccount() {
    const request = {
        account: formData.userId
    }
    http.post("/user/account/freeze", request).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '用户冻结成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageUserInfo()
        }
    })
}

function unFreezeAccount() {
    const request = {
        account: formData.userId
    }
    http.post("/user/account/unfreeze", request).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '用户解冻成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageUserInfo()
        }
    })
}

function cancelAccount() {
    const request = {
        account: formData.userId
    }
    http.post("/user/account/cancel", request).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '用户解冻成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageUserInfo()
        }
    })
}

function resetAccountPwd() {
    const request = {
        account: formData.userId
    }
    http.post("/user/account/pwd/reset", request).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '用户密码重置成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageUserInfo()
        }
    })
}

const roleModelVisiable = ref<boolean>(false)
const userId = ref<string | undefined>("")
const userName = ref<string | undefined>("")

function openUserAuth(row: RowData) {
    router.push({
        name: 'auth',
        query: { objId: row.userId, objType: "0" }
    })
}

function openUserRole(row: RowData) {
    userId.value = row.userId
    userName.value = row.userName
    roleModelVisiable.value = true
}
</script>

<template>
    <div id="flame-container">
        <div class="search">
            <n-form :model="userInfoSearchFormValue" inline label-placement="left">
                <n-form-item label="用户编号" path="userId">
                    <n-input v-model:value="userInfoSearchFormValue.userId" placeholder="请输入用户编号" clearable />
                </n-form-item>
                <n-form-item label="姓名" path="userName">
                    <n-input v-model:value="userInfoSearchFormValue.userName" placeholder="请输入姓名" clearable />
                </n-form-item>
                <n-form-item>
                    <n-button attr-type="button" @click="pageUserInfo()">查询</n-button>
                </n-form-item>
            </n-form>
        </div>
        <div class="btn-group"><n-button v-if="userStore.hasAuth('user:add')" attr-type="button"
                @click="openAddUserInfo()">新增</n-button>
        </div>
        <div class="data-table">
            <n-data-table :scroll-x="2196" :scrollbar-props="{ trigger: 'none' }" style="height:100%" flex-height
                :columns="userInfoTableColumns" :data="userInfoData.list" :bordered="false" />
        </div>
        <div class="pagination">
            <n-pagination style="float:right" v-model:page="userInfoData.pageNum" :page-size="userInfoData.pageSize"
                :item-count="userInfoData.total" :page-sizes="[5, 10, 30, 50, 100]" :on-update-page="pageNumChange"
                :on-update-page-size="pageSizeChange" show-quick-jumper show-size-picker />
        </div>
    </div>
    <n-modal v-model:show="visiable">
        <n-card style="width: 800px" :title="title">
            <n-form ref="formRef" :model="formData" :rules="formRules" label-width="116px" label-placement="left"
                require-mark-placement="left">
                <n-grid :cols="2" :x-gap="12">
                    <n-form-item-gi :span="1" label="用户编号(账号)" path="userId">
                        <n-input v-model:value="formData.userId" disabled placeholder="请生成用户编号(账号)" clearable />
                        <n-button @click="generateAccount()">生成</n-button>
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="所属机构" path="orgCode">
                        <n-tree-select v-model:value="formData.orgCode" :options="orgStore.orgInfoTree" default-value=""
                            placeholder="请选择所属机构" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="姓名" path="userName">
                        <n-input v-model:value="formData.userName" placeholder="请输入姓名" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="性别" path="sex">
                        <n-radio-group v-model:value="formData.sex" name="radiogroup">
                            <n-space>
                                <n-radio v-for="dict in dictStore.dict('SEX')" :key="dict.value" :value="dict.value">
                                    {{ dict.label }}
                                </n-radio>
                            </n-space>
                        </n-radio-group>
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="民族" path="nationality">
                        <n-select v-model:value="formData.nationality" :options="dictStore.dict('NATIONALITY')"
                            placeholder="请选择民族" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="出生日期" path="birthday">
                        <n-date-picker style="width:100%" v-model:formatted-value="formData.birthday"
                            value-format="yyyy-MM-dd" placeholder="请选择出生日期" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="证件类型" path="idType">
                        <n-select v-model:value="formData.idType" :options="dictStore.dict('ID_TYPE')" placeholder="请选择证件类型"
                            clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="证件号码" path="idCode">
                        <n-input v-model:value="formData.idCode" placeholder="请输入证件号码" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="证件开始日期" path="idBeginDate">
                        <n-date-picker style="width:100%" v-model:formatted-value="formData.idBeginDate"
                            value-format="yyyy-MM-dd" placeholder="请选择证件开始日期" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="证件结束日期" path="idExpDate">
                        <n-date-picker style="width:100%" v-model:formatted-value="formData.idExpDate"
                            value-format="yyyy-MM-dd" placeholder="请选择证件结束日期" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="手机号" path="telephone">
                        <n-input v-model:value="formData.telephone" placeholder="请输入手机号" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="1" label="邮箱" path="email">
                        <n-input v-model:value="formData.email" placeholder="请输入邮箱" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="2" label="联系地址" path="address">
                        <n-input v-model:value="formData.address" placeholder="请输入联系地址" clearable />
                    </n-form-item-gi>
                    <n-form-item-gi :span="2" label="备注" path="remark">
                        <n-input v-model:value="formData.remark" placeholder="请输入备注" clearable />
                    </n-form-item-gi>
                </n-grid>
            </n-form>
            <template #footer>
                <n-space justify="end">
                    <n-button attr-type="button" @click="visiable = false">取消</n-button>
                    <n-button attr-type="button" @click="submit()">提交</n-button>
                </n-space>
            </template>
        </n-card>
    </n-modal>
    <user-role-model v-model:role-model-visiable="roleModelVisiable" :user-id="userId" :user-name="userName" />
</template>

<style scoped>
.display-flex-end {
    display: flex;
    width: 100%;
    justify-content: flex-end;
}
</style>